Chart declarations =================== The plotting at the end of a forecast round is always the same twenty lines. Pick a range, loop over names, subplot, plot, title, grid, shade the forecast span, repeat for the next scenario. It gets written fresh in every project, it is never quite the same twice, and it is the part of a round most likely to be wrong in a way nobody notices. ``rise.plot.rcharts`` replaces it with a declaration. .. code-block:: matlab cb = rise.plot.rcharts(DateRange=range, GridSize=[2 3]); xregion(cb, forecastStart, forecastEnd); cb + ["Output gap: ygap" "Inflation: 4*(p - p{-1})" "^Policy rate: r"]; plot(cb, db); Each string is one chart. A caption may precede a colon. What follows is an **expression evaluated against the data**, not merely a field name, so transformations are written inline in the same lag notation a model file uses. Where MATLAB already has a name for something, that name is used and the function carrying it is overloaded, so there is less to learn: .. list-table:: :header-rows: 1 :widths: 34 66 * - Call - What it does * - ``cb + "Caption: expr"`` - adds a chart; ``append(cb, ...)`` is the same thing * - ``plot(cb, db)`` - draws the charts * - ``xline(cb, date)``, ``yline(cb, y)`` - add reference lines; asking twice draws once * - ``xregion(cb, from, to)`` - adds a shaded span, one row per period * - ``grid(cb, 'off')`` - turns the grid off * - ``reset(cb)`` - empties the list and keeps every setting * - ``isempty(cb)`` - true when nothing has been added ``GridSize`` is ``[rows cols]``, spelled as a tiled layout spells it. .. contents:: :local: :depth: 2 The four marks --------------- .. list-table:: :header-rows: 1 :widths: 30 70 * - Form - Meaning * - ``Caption: expression`` - the caption is what precedes the colon * - ``^expression`` - do not apply the chart-level transform to this chart * - ``?`` inside an expression - one series per member of ``Variants``, with a legend * - ``--`` alone - a page break; start a new figure here A colon also appears inside expressions, in a range. The test is brackets: a candidate caption containing one is not a caption, so ``y(1:4)`` stays whole while ``\pi^e: p`` splits. Operator characters are allowed in a caption on purpose, because the interpreter is on by default and the captions worth writing use them. Variants --------- A scenario, regime, model or vintage comparison is the case a loop over names handles worst. It is one line here: .. code-block:: matlab cb.Variants = ["Output", "Output_low"]; cb + "Output, both scenarios: ?"; The placeholder is replaced by each member in turn, the resulting series share one chart, and the legend follows from the variant list. **Overlaid, or one tile each.** Overlaying is right for two scenarios on one scale. It stops being readable once there are several, or once they differ enough in level that the interesting one is a flat line at the bottom. ``VariantLayout`` chooses: .. code-block:: matlab cb.VariantLayout = "separate"; Each variant then gets its own tile, captioned with the subject above and the case below, and the legend is dropped as redundant. This is what a grammar of graphics calls faceting; the idea comes from there rather than from any macro-modelling toolbox. The split happens before pagination, so ``ChartsPerFigure`` and the page breaks count the tiles that actually get drawn. Shading and reference lines ---------------------------- ``Shade`` is handed to RISE's own ``shade``, so it takes **one row per period** and more than one episode can be marked from a single declaration: .. code-block:: matlab xregion(cb, forecastStart, forecastEnd); % add one span xregion(cb, rec2Start, rec2End); % and another cb.Shade = [rec1Start rec1End; rec2Start rec2End]; % or set them all The shading sits behind the data and leaves the vertical limits alone. ``XLine`` and ``YLine`` hold vertical and horizontal reference lines, set directly or added with ``xline`` and ``yline``. Asking for the same line twice draws it once, which matters because ``YLine`` already carries a line at zero. All three are converted to the axis's own units, so a date lands where the calendar says rather than in the first century. Specification and rendering are separate ----------------------------------------- ``resolve`` works the charts out against data and opens no figure: .. code-block:: matlab spec = resolve(cb, db); Each entry carries the resolved caption, the expression as written, the series, the legend, whether a person wrote the caption, whether the chart failed and why, and whether it is a page break. ``plot`` consumes exactly this and adds tiling, annotation, the named style and the date axis. That seam is the point. Figures and a figure in a published report read the same structure, so the two cannot drift apart, and a further backend needs no change here. When the range is applied -------------------------- ``DateRange`` cuts the series down **after** the expression is evaluated and the transform applied. A backward-looking expression needs the observations before the window in order to produce the first point inside it; trimming the data first would quietly cost the opening period of every growth-rate chart. The window is also clipped to what each series actually has. A chart written as a growth rate is one period shorter than the levels beside it, and asking such a series for the full window is an error. A broken chart keeps its tile ------------------------------ The default is to carry on: .. code-block:: none chart 2 (Ouput) failed: Unrecognized function or variable 'Ouput'. The failure is reported by index and by the string as written, and the tile stays, marked. Dropping it would shift every chart after it up one place, which is how a reader ends up looking at the wrong series and believing it. Set ``OnError`` to ``"stop"`` to raise ``RISE:rcharts:badExpression`` instead. Captions --------- Resolution order, in full: an explicit caption; then the series ``description`` when ``UseDescription`` is on; then the expression itself. Arithmetic does not carry a description, so a computed chart falls through to its formula, which is the right way round. ``LineBreak`` splits a caption into lines, giving a subtitle. ``Interpreter`` chooses how the text is read and defaults to ``"tex"``, because the material is full of Greek letters and subscripts. A caption a person wrote passes through it untouched. A name the declaration generated is escaped first, so a variable called ``Output_low`` does not reach the page as Output with a subscript. The distinction is kept per line, which is what lets a faceted caption carry an authored subject above a generated variant name. The named style ---------------- .. code-block:: matlab cb.Style = "rise"; % or "plain" One place for color order, line width, grid weight, font size, shade color and rule color. A project sets it once and every figure follows; changing the name changes every figure with no other edit. An unknown name is refused by ``RISE:chartstyle:unknown``, which lists the styles that exist. Adding a style means adding a case in ``rise.plot.chartstyle`` and nothing else. Property summary ----------------- .. list-table:: :header-rows: 1 :widths: 28 72 * - Group - Properties * - data - ``DateRange``, ``Transform``, ``Decimals`` * - captions - ``UseDescription``, ``ShowExpression``, ``LineBreak`` * - variants - ``Variants``, ``VariantMark``, ``VariantLayout`` * - layout - ``GridSize``, ``ChartsPerFigure`` * - annotation - ``Shade``, ``XLine``, ``YLine``, ``Grid`` * - style - ``Style``, ``PlotFcn``, ``Interpreter``, and the pass-through buckets ``FigureOptions``, ``AxesOptions``, ``PlotOptions``, ``TitleOptions`` * - behavior - ``OnError`` A property name that does not exist is refused by the constructor rather than becoming a new property. Worked example: ``rise-modern-tutorials/Reporting/rcharts``. .. seealso:: :doc:`Plotting tools`, :doc:`Reporting/Publishing a script`